package com.chenjun.core.auth.service;

import java.io.IOException;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.Set;

import org.apache.log4j.Logger;
import org.apache.shiro.spring.web.ShiroFilterFactoryBean;
import org.apache.shiro.web.filter.mgt.DefaultFilterChainManager;
import org.apache.shiro.web.filter.mgt.PathMatchingFilterChainResolver;
import org.apache.shiro.web.servlet.AbstractShiroFilter;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.io.ClassPathResource;
import org.springframework.util.CollectionUtils;

import com.chenjun.common.OrderedProperties;
import com.chenjun.common.model.DataGridModel;
import com.chenjun.core.dao.generator.entity.SysResource;
import com.chenjun.core.dao.generator.entity.SysRole;
import com.chenjun.core.service.sys.SysResourceService;
import com.chenjun.core.service.sys.SysRoleService;

/**
 * 
 * @Description: 动态权限获取验证服务类 
 * @author yanjinyin
 * @date 2017年7月23日 下午4:46:14
 */
public class AuthService {

	private static final Logger logger = Logger.getLogger(AuthService.class);

	// 注意/r/n前不能有空格

	private static final String CRLF = "\r\n";

	private static final String LAST_AUTH_STR = "/** =authc\r\n";

	@Autowired
	private ShiroFilterFactoryBean shiroFilterFactoryBean;
	
	@Autowired
	private SysRoleService 		sysRoleService;

	@Autowired
	private SysResourceService  	sysResourceService;

	/**
	 * 获取过滤器规则链
	 * 
	 * @return
	 * @see IAuthService#loadFilterChainDefinitions()
	 */
	public String loadFilterChainDefinitions() {

		StringBuffer sb = new StringBuffer("");

		sb.append(getFixedAuthRule());
		
		sb.append(getDynaAuthRule());
		
		sb.append(LAST_AUTH_STR);

		return sb.toString();
	}

	// 得到固定权限验证规则串
	private String getFixedAuthRule() {

		StringBuffer sb = new StringBuffer("");
		ClassPathResource cp = new ClassPathResource("fixed_auth_res.properties");
		Properties properties = new OrderedProperties();
		try {
			properties.load(cp.getInputStream());
		} catch (IOException e) {
			logger.error("loadfixed_auth_res.properties error!", e);
			throw new RuntimeException("load fixed_auth_res.properties error!");

		}

		for (Iterator<Object> its = properties.keySet().iterator(); its.hasNext();) {
			String key = (String) its.next();
			sb.append(key).append(" = ").append(properties.getProperty(key).trim()).append(CRLF);

		}

		logger.info("auth rules:\n" + sb.toString());

		return sb.toString();
	}
	
    // 根据角色，得到动态权限规则
    private String getDynaAuthRule() {

        StringBuffer sb = new StringBuffer("");
        Map<String, Set<String>> rules = new HashMap<String, Set<String>>(0);

        //获取角色列表
        DataGridModel dgm = new DataGridModel();
        dgm.setStart(0);
        dgm.setRows(0);
        List<SysRole> roles = sysRoleService.doListByCondition(dgm);
        if(!CollectionUtils.isEmpty(roles)){
        	for(SysRole role:roles){
        		dgm.getParams().put("roleId",role.getId());
        		List<SysResource> rs = sysResourceService.doListByCondition(dgm);
        		for (SysResource resource : rs) {
                    String url = resource.getUrl();
                    if (!rules.containsKey(url)) {
                        rules.put(url, new HashSet<String>(0));
                    }
//                    rules.get(url).add(role.getName());
                    rules.get(url).add(role.getId());
                }
        	}
        	
        	for (Map.Entry<String, Set<String>> entry : rules.entrySet()) {
                sb.append(entry.getKey()).append(" = ")
                                .append("authc,anyofroles")
                                .append(entry.getValue()).append(CRLF);
            }
        }
        
        logger.info("dynamic  rules:\n"+sb);
        
        return sb.toString();
    }

	/**
	 * (非 Javadoc)
	 * 
	 * 
	 * @see IAuthService#reCreateFilterChains()
	 */
	public synchronized void reCreateFilterChains() {
		AbstractShiroFilter shiroFilter = null;

		try {
			shiroFilter = (AbstractShiroFilter) shiroFilterFactoryBean.getObject();
		} catch (Exception e) {
			logger.error("getShiroFilter from shiroFilterFactoryBean error!", e);
			throw new RuntimeException("get ShiroFilter from shiroFilterFactoryBean error!");
		}

		PathMatchingFilterChainResolver filterChainResolver = (PathMatchingFilterChainResolver) shiroFilter.getFilterChainResolver();
		DefaultFilterChainManager manager = (DefaultFilterChainManager) filterChainResolver.getFilterChainManager();

		// 清空老的权限控制
		manager.getFilterChains().clear();

		shiroFilterFactoryBean.getFilterChainDefinitionMap().clear();
		shiroFilterFactoryBean.setFilterChainDefinitions(loadFilterChainDefinitions());
		// 重新构建生成

		Map<String, String> chains = shiroFilterFactoryBean.getFilterChainDefinitionMap();
		for (Map.Entry<String, String> entry : chains.entrySet()) {
			String url = entry.getKey();
			String chainDefinition = entry.getValue().trim().replace(" ","");
			manager.createChain(url, chainDefinition);
		}
	}

}
